//
//  UNAnimationTool.swift
//  Unibet
//
//  Created by HaoSheng on 2020/4/20.
//  Copyright © 2020 蜗牛. All rights reserved.
//

import UIKit

///动画样式
public enum UNAnimationType {
    ///底部上移
    case bottomMobile(time:Double = 0.2)
    /// 自动布局view的底部上移
    case bottomLayoutMobile(time:Double = 0.2)
    ///中心缩放
    case centerZoom(maxTime:Double = 0.3,minTime:Double = 0.2)
    ///渐入透明
    case Gradually(time:Double = 0.2)
    
    // 添加计算属性提取时间
    var time: Double {
        switch self {
        case .bottomMobile(let time),
             .bottomLayoutMobile(let time),
             .Gradually(let time):
            return time
        case .centerZoom(let maxTime, _):
            return maxTime // 或其他逻辑
        }
    }
    
}


class UNAnimationViewModel{
    var view: UIView
    var backgroundView: UIView?
    ///动画样式
    var animationType: UNAnimationType = .Gradually()
    ///点击背景是否移除view
    var cancelAction: Bool = true
    /// 底部上移使用的布局
    var constraints: [NSLayoutConstraint] = []
    
    init(view: UIView, backgroundView: UIView? = nil, animationType: UNAnimationType = .Gradually(), cancelAction: Bool = true, constraints: [NSLayoutConstraint] = []) {
        self.view = view
        self.backgroundView = backgroundView
        self.animationType = animationType
        self.cancelAction = cancelAction
        self.constraints = constraints
    }
    
}

@MainActor
open class UNAnimationTool {
    
    public static let share: UNAnimationTool = UNAnimationTool()
    
    /// 点击背景移除block
    public var cancelClcikBlock: () -> Void = {}
    
    private init() { }
    
    ///从屏幕下方弹出自定义view time弹出动画时间 showBackground是否显示背景 alpha背景透明度 ,cancelAction:true点击背景推出视图
    var views: [UNAnimationViewModel] = []
    
    
    
// MARK: - showView
    
    /// 分类弹出动画方法
    public static func ShowAnimationView(type:UNAnimationType = .Gradually(),view: UIView ,superView: UIView = getWindow ,showBackground: Bool = true ,alpha: CGFloat = 0.3 ,cancelAction:Bool = true){
        
        switch type {
        case .Gradually(let time):
            ShowGraduallyViewAnimationView(view: view,superView: superView,time: time,showBackground: showBackground,alpha: alpha,cancelAction: cancelAction)
            break
        case .bottomMobile(let time):
            ShowMobileViewAnimationView(view: view,superView: superView,time: time,showBackground: showBackground,alpha: alpha,cancelAction: cancelAction)
            break
        case .bottomLayoutMobile(let time):
            ShowMobileLayoutAnimationView(view: view,superView: superView,time: time,showBackground: showBackground,alpha: alpha,cancelAction: cancelAction)
            break
        case .centerZoom(let maxTime,let minTime):
//            ShowZoomViewAnimationView(view: view,superView: superView,maxTime: maxTime, minTime: minTime, showBackground: showBackground,alpha: alpha,cancelAction: cancelAction)
            break
        }
        
    }
    
    /// 分类隐藏动画方法
    public static func DownAnimationView(type:UNAnimationType = .Gradually(),time: Double? = nil,completion: Block? = nil){
        
//        let type = UNAnimationType.share.views.last!.animationType
//        let type = UNAnimationTool.share.cancelClcik()
        
        switch type {
        case .Gradually(let time):
            UNAnimationTool.DownGraduallyViewAnimationView(time: time,completion: completion)
            break
        case .bottomMobile(let time):
            UNAnimationTool.DownMobileViewAnimationView(time: time,completion: completion)
            break
        case .bottomLayoutMobile(let time):
            UNAnimationTool.DownMobileViewAnimationView(completion: completion)
            break
        case .centerZoom(let maxTime,let minTime):
//            DownZoomViewAnimationView(backgroundViewRemove: backgroundViewRemove,time: time)
            break
        }
    }
    
    
    
    // MARK: - 详细动画方法
    
    /**
     从屏幕下方弹出自定义view
     - parameter view: 弹出自定义view
     - parameter time: 弹出动画时间
     - parameter showBackground: true显示背景
     - parameter alpha: 背景透明度
     - parameter cancelAction: true点击背景推出视图
    */ 
    public static func ShowMobileViewAnimationView(view: UIView ,superView:UIView = getWindow ,time: Double? = nil ,showBackground: Bool = true ,alpha: CGFloat = 0.3 ,cancelAction:Bool = false){
        
        var mod = UNAnimationViewModel(view: view)
        mod.animationType = .bottomMobile(time: time ?? mod.animationType.time)
        mod.cancelAction = cancelAction
        UNAnimationTool.share.views.append(mod)
        
        //记录原来的位置
        let frame = view.frame 
        
        //背景颜色
        let backColor = UIColor.FromRGB(R: 0, G: 0, B: 0, A: alpha)
        
        //设置动画前在屏幕下 
        view.frame = .init(x: view.left, y: MainHeight, width: view.width, height: view.height)
        
        setBackground(view: view, superView: superView)
        
        UIView.transition(with: getWindow, duration: mod.animationType.time, options: .curveEaseInOut, animations: {
            
            view.frame = frame
            
            if showBackground == true {
                mod.backgroundView?.backgroundColor = backColor
            }
             
        }, completion: nil)
        
    }
    
    
    
    /**
     从屏幕下方弹出自定义自动布局的view
        只支持贴着底部的布局
     - parameter view: 弹出自定义view
     - parameter time: 弹出动画时间
     - parameter showBackground: true显示背景
     - parameter alpha: 背景透明度
     - parameter cancelAction: true点击背景推出视图
    */
    public static func ShowMobileLayoutAnimationView(view: UIView ,superView:UIView = getWindow ,time: Double? = nil ,showBackground: Bool = true ,alpha: CGFloat = 0.3 ,cancelAction:Bool = false){
        
        var mod = UNAnimationViewModel(view: view)
        mod.animationType = .bottomLayoutMobile(time: time ?? mod.animationType.time )
        mod.cancelAction = cancelAction
        UNAnimationTool.share.views.append(mod)
        
        // 取消系统自动添加约束
        view.translatesAutoresizingMaskIntoConstraints = false
        // 初始约束
        var cons = [
            view.leadingAnchor.constraint(equalTo: superView.leadingAnchor, constant: 0),
            view.trailingAnchor.constraint(equalTo: superView.trailingAnchor, constant: 0),
            view.topAnchor.constraint(equalTo: superView.bottomAnchor, constant: 0)
        ]
        
        mod.constraints = cons
        
        //背景颜色
        let backColor = UIColor.FromRGB(R: 0, G: 0, B: 0, A: alpha)
        
        //设置动画前在屏幕下
        view.frame = .init(x: view.left, y: MainHeight, width: view.width, height: view.height)
        
        setBackground(view: view, superView: superView)
        
        // 在动画之前将view放到屏幕底部
        // 激活约束
        NSLayoutConstraint.activate(cons)
        // 立即更新布局
        superView.layoutIfNeeded()
        
        UIView.transition(with: getWindow, duration: mod.animationType.time, options: .curveEaseInOut, animations: {
            
            NSLayoutConstraint.deactivate(cons)
            cons = [
                view.leadingAnchor.constraint(equalTo: superView.leadingAnchor, constant: 0),
                view.trailingAnchor.constraint(equalTo: superView.trailingAnchor, constant: 0),
                view.bottomAnchor.constraint(equalTo: superView.bottomAnchor, constant: 0)
            ]
            mod.constraints = cons
            // 激活约束
            NSLayoutConstraint.activate(cons)
            // 立即更新布局
            superView.layoutIfNeeded()
            
            if showBackground == true {
                UNAnimationTool.share.views.last?.backgroundView?.backgroundColor = backColor
            }
             
        }, completion: nil)

    }
    
    
    /**
     缩放弹出自定义view
     - parameter view: 弹出自定义view
     - parameter maxTime: 放大动画时间
     - parameter minTime: 缩小动画时间
     - parameter showBackground: true显示背景
     - parameter alpha: 背景透明度
     - parameter cancelAction: true点击背景推出视图
    */
//    public static func ShowZoomViewAnimationView(view: UIView ,superView:UIView = getWindow ,maxTime: Double = 0.3 ,minTime: Double = 0.2 ,showBackground: Bool = true ,alpha: CGFloat = 0.3 ,cancelAction:Bool = false){
//        
//        UNAnimationTool.share.view = view
//        UNAnimationTool.share.animationType = .centerZoom()
//        UNAnimationTool.share.cancelAction = cancelAction
//        
//        //背景颜色
//        let backColor = UIColor.FromRGB(R: 0, G: 0, B: 0, A: alpha)
//        
//        //设置动画前在屏幕中央
//        view.center = .init(x: superView.width/2, y: superView.height/2)
//        
//        ShowViewAnimation(view: view, superView: superView) {
//            
//            // 第一步：将view宽高缩至无限小（点）
//            view.transform = .init(scaleX: CGFloat.leastNormalMagnitude, y: CGFloat.leastNormalMagnitude)
//            
//            UIView.animate(withDuration: maxTime) {
//                // 第二步： 以动画的形式将view慢慢放大至原始大小的1.2倍
//                view.transform = .init(scaleX: 1.2, y: 1.2)
//                if showBackground == true {
//                    UNAnimationTool.share.backgroundBtn.backgroundColor = backColor
//                }
//            } completion: { finished in
//                UIView.animate(withDuration: minTime, animations: {
//                    // 第三步： 以动画的形式将view恢复至原始大小
//                    view.transform = .identity
//                }, completion: nil)
//            }
//            
//        }
//    }
    
    
    /**
     渐入不透明弹出自定义view
     - parameter view: 弹出自定义view
     - parameter time: 弹出动画时间
     - parameter showBackground: true显示背景
     - parameter alpha: 背景透明度
     - parameter cancelAction: true点击背景推出视图
    */
    public static func ShowGraduallyViewAnimationView(view: UIView ,superView: UIView = getWindow ,time: Double? = nil ,showBackground: Bool = true ,alpha: CGFloat = 0.3 ,cancelAction:Bool = true){
        
        var mod = UNAnimationViewModel(view: view)
        mod.animationType = .Gradually(time: time ?? mod.animationType.time)
        mod.cancelAction = cancelAction
        UNAnimationTool.share.views.append(mod)
        
        //背景颜色
        let backColor = UIColor.FromRGB(R: 0, G: 0, B: 0, A: alpha)
        
        view.alpha = 0
        setBackground(view: view, superView: superView)
        
        UIView.transition(with: superView, duration: mod.animationType.time, options: .curveEaseIn, animations: {
            
            if showBackground == true {
                mod.backgroundView?.backgroundColor = backColor
            }
            
            view.alpha = 1
            
        }, completion: nil )
        
    }
    
    
    /**
     弹出自定义view，用于自定义动画
     - parameter view: 弹出自定义view
     - parameter animation: 动画
    */
    public static func setBackground(view: UIView,superView: UIView = getWindow){
        
        //将view添加到window
        superView.addSubview(view)
        
        //用tag从window上获取背景view
        var mod = UNAnimationTool.share.views.last
        
        let btn = UIButton.init(frame: .init(x: 0, y: 0, width: MainWidth, height: MainHeight))
        btn.backgroundColor = UIColor.FromRGB(R: 0, G: 0, B: 0, A: 0)
        btn.tag = 666 + UNAnimationTool.share.views.count
        btn.addTarget(UNAnimationTool.share, action: #selector(cancelClcik), for: .touchUpInside)
        
        mod?.backgroundView = btn
        
        //将背景添加到window
        superView.addSubview( btn )
        //将需要弹出的view放到window的最顶层
        superView.bringSubviewToFront(view)
        
    }
    
    
// MARK: - removeView
    
    ///底部移除view
    public static func DownMobileViewAnimationView(backgroundViewRemove: Bool = true, time: Double? = nil,completion: Block? = nil){
        
        if UNAnimationTool.share.views.count < 1 {
            return
        }
        
        let mod = UNAnimationTool.share.views.last!
        var view = mod.view
        
        let frame: CGRect = .init(x: view.left, y: MainHeight, width: view.width, height: view.height)
        
        removeAnimationView(time: time == nil ? mod.animationType.time : time!) {
            view.frame = frame
        } completion: {
            view.removeFromSuperview()
            completion?()
        }

        
    }
    
    
//    ///底部移除view 自动布局方式
//    public static func DownMobileLayoutAnimationView(time: Double? = nil){
//        
//        if UNAnimationTool.share.views.count < 1 {
//            return
//        }
//        var mod = UNAnimationTool.share.views.last!
//        var view = mod.view
//        
//        NSLayoutConstraint.deactivate(mod.constraints)
//        mod.constraints = []
//        
//        let superView = view.superview ?? UIView()
//        // 初始约束
//        let cons = [
//            view.leadingAnchor.constraint(equalTo: superView.leadingAnchor, constant: 0),
//            view.trailingAnchor.constraint(equalTo: superView.trailingAnchor, constant: 0),
//            view.topAnchor.constraint(equalTo: superView.bottomAnchor, constant: 0)
//        ]
//        
//        removeAnimationView(time: time == nil ? mod.animationType.time : time!) {
//            
//            // 激活约束
//            NSLayoutConstraint.activate(cons)
//            // 立即更新布局
//            superView.layoutIfNeeded()
//            
//        } completion: {
//            view.removeFromSuperview()
//        }
//    }
    
    
    ///缩放移除view
//    public static func DownZoomViewAnimationView(view: UIView = UNAnimationTool.share.view, backgroundViewRemove: Bool = true, time: Double = 0.2){
//        
//        removeAnimationView(backgroundViewRemove: backgroundViewRemove, time: time) {
//            view.transform = .init(scaleX: 0.1, y: 0.1)
//        } completion: {
//            view.removeFromSuperview()
//        }
//        
//    }
    
    ///渐入透明移除view
    public static func DownGraduallyViewAnimationView(time: Double? = nil,completion: Block? = nil){
        
        if UNAnimationTool.share.views.count < 1 {
            return
        }
        var mod = UNAnimationTool.share.views.last!
        var view = mod.view
        
        removeAnimationView(time: time == nil ? mod.animationType.time : time!) {
            view.alpha = 0
        } completion: {
            view.removeFromSuperview()
            completion?()
        }
        
    }
    
    ///移除view backgroundViewRemove是否移除背景view time动画时间
    public static func removeAnimationView(time: Double = 0.2, animate:@escaping ()->Void ,completion:@escaping ()->Void){
        
        if UNAnimationTool.share.views.count < 1 {
            return
        }
        
        if let mod = UNAnimationTool.share.views.last {
            
            UIView.animate(withDuration: time) {
                
                mod.backgroundView?.backgroundColor = UIColor.FromRGB(R: 0, G: 0, B: 0, A: 0)
                
                animate()
                
            } completion: { finished in
                
                mod.backgroundView?.removeFromSuperview()
                let vs = UNAnimationTool.share.views
                UNAnimationTool.share.views.removeAll(where: { $0 === mod })
                
                completion()
                
            }
            
        }
        
    }
    
    
// MARK: - 事件
    
    ///点击背景移除视图
    @objc public func cancelClcik(){
        
        cancelClcikBlock()
        
        if views.count < 1 {
            return
        }
        
        let mod = views.last!
        
        if mod.cancelAction {
            switch mod.animationType {
            case .bottomMobile:
                UNAnimationTool.DownMobileViewAnimationView()
            case .centerZoom:
                break
//                UNAnimationTool.DownZoomViewAnimationView()
            case .Gradually:
                UNAnimationTool.DownGraduallyViewAnimationView()
            case .bottomLayoutMobile(time: let time):
                UNAnimationTool.DownMobileViewAnimationView()
//                UNAnimationTool.DownMobileLayoutAnimationView()
                break
            }
        }
        
    }
    
    
}
